/* gpusrpgm.p - validate the user-specified program                     */
/* Copyright 1986-2002 QAD Inc., Carpinteria, CA, USA.                  */
/* All rights reserved worldwide.  This is an unpublished work.         */
/*V8:ConvertMode=NoConvert                                              */
/* Revision: 8.0        Last modified: 04/28/94         By: aed */
/* Revision: 8.3        Last modified: 04/05/95         By: aed */
/* Revision: 8.5        Last Modified: 10/16/95         By: jpm  *J08V*/
/* Revision: 8.5        Last modified: 05/14/96         By: rkc  *G1VJ*/


/* REVISION: 8.6E     LAST MODIFIED: 02/23/98   BY: *L007* A. Rahane */
/* REVISION: 8.6E     LAST MODIFIED: 04/13/98   BY: *G2RK* Vijaya Pakala */
/* REVISION: 8.6E     LAST MODIFIED: 05/09/98   BY: *J2DD* Kawal Batra   */
/* REVISION: 8.6E     LAST MODIFIED: 10/04/98   BY: *J314* Alfred Tan    */
/* REVISION: 9.0      LAST MODIFIED: 12/02/99   BY: *L0MB* Raphael T     */
/* REVISION: 9.1      LAST MODIFIED: 08/13/00   BY: *N0KS* myb           */
/*************************************************************************/

/*J2DD** ADDED NO-UNDO, ASSIGN THROUGHOUT **/

{mfdeclre.i}

/* ********** Begin Translatable Strings Definitions ********* */

&SCOPED-DEFINE gpusrpgm_p_1 "Return value"
/* MaxLen: Comment: */

&SCOPED-DEFINE gpusrpgm_p_2 "Runnable"
/* MaxLen: Comment: */

&SCOPED-DEFINE gpusrpgm_p_3 "Program to look up"
/* MaxLen: Comment: */

&SCOPED-DEFINE gpusrpgm_p_4 "Program label"
/* MaxLen: Comment: */

/* ********** End Translatable Strings Definitions ********* */


define input-output parameter pgm-name as character
                                        label {&gpusrpgm_p_3}  no-undo.
define output parameter pgm-label as character label {&gpusrpgm_p_4}  no-undo.
define output parameter passed as logical label {&gpusrpgm_p_1}  no-undo.
define output parameter isProgram as logical label {&gpusrpgm_p_2}  no-undo.

{mf1.i}

define shared variable menu as character.

define variable cselection as character format "x(16)" no-undo.
define variable menuselection as character no-undo.
define variable lastmenu as character no-undo.
define variable thismenu as character no-undo.
define variable thisselection as integer no-undo.
define variable saveselection as integer no-undo.
define variable savemenu as character no-undo.
define variable run_file as character no-undo.
define variable selchar as character no-undo.
define variable isaprogram like mfc_logical no-undo.
define variable numericselection like mfc_logical no-undo.
define variable lastperiod as integer no-undo.
define variable periods as integer no-undo.
define buffer mnddet for mnd_det.
define variable passnbr like mnd_nbr no-undo.
define variable i as integer no-undo.
define variable j as integer no-undo.
/* define variable menu_title as char format "x(60)" extent 9. */
/* define variable menu1 as character extent 9. */

define variable can_do_menu as logical  no-undo.
define variable user_excluded like mfc_logical  no-undo.
define variable tmp_canrun as character  no-undo.
define variable group_indx as integer  no-undo.

define variable new-exec-pgm-1 as character no-undo.         /*G2RK*/
define variable new-exec-pgm-2 as character no-undo.         /*G2RK*/

main-loop:
do:
assign passed = no.    /* initial result code */
if menu = "" then do:
  assign
    menu = "0"
    printdefault = "".
end.

assign cselection = pgm-name.
if cselection = "" then leave.

assign i = index(cselection,",").
do while i > 0:
    assign
      substr(cselection,i,1) = "."
      i = index(cselection,",").
end.

assign menuselection = menu + "." + cselection.
if cselection begins "." then
   assign menuselection = "0" + cselection.

if cselection = "" or cselection = "."
    or index(cselection,"/") > 0
    or index(cselection,"[") > 0
    or index(cselection,"~\") > 0
    or cselection begins "help" or cselection begins "dict" then do:
    {gprun.i ""gpmsg.p""
      "(input 13, input 3)"
    }
    /* INVALID SELECTION. Please re-enter */
    leave.
end. /* cselection = "" */

assign
  numericselection = yes
  i = 1
  lastperiod = 0
  periods = 0.

do while i <= length(menuselection):
    assign selchar = substring(menuselection,i,1).
    if selchar = "." then do:
      assign
        lastperiod = i
        periods = periods + 1.
    end.
    else if selchar < "0" or selchar > "9" then
       assign numericselection = no.
    assign i = i + 1.
end. /* do while */

if selchar = "." then do:
    /* ENTERED SELECTION CANT END WITH A PERIOD */
    {gprun.i ""gpmsg.p""
      "(input 13, input 3)"
    }
    /* INVALID SELECTION. Please re-enter */
    leave.
end. /* selchar = "." */

assign isaprogram = no.

/* IF THEY ENTERED A NUMERIC MENU SELECTION EG 23 or 23.21.1 etc */
if numericselection then do:
    if menuselection begins "0." then do:
        if periods = 1 then
           assign thismenu = "0".
        else
           assign thismenu = substring(menuselection,3,lastperiod - 3).
    end. /* if menuselection begins "0" */
    else
      assign thismenu = substring(menuselection,1,lastperiod - 1).

    assign
    thisselection = integer(substring (menuselection,lastperiod + 1,16)).

/*J2DD** find mnd_det where mnd_nbr = thismenu and mnd_select = thisselection**/
/*J2DD** no-lock no-error.                                                   **/
/*J2DD*/ for first mnd_det
/*J2DD*/ fields(mnd_exec mnd_name mnd_nbr mnd_select)
/*J2DD*/ where mnd_nbr = thismenu and mnd_select = thisselection no-lock: end.

    if not available mnd_det then do:
        {gprun.i ""gpmsg.p""
          "(input 13, input 3)"
        }
        /* INVALID SELECTION.  Please re-enter. */
        leave.
    end. /* if not available ... */

/*
    if mnd_nbr = "0" then
       assign menu_title[j] = string(mnd_select) + ". ".
    else
       assign menu_title[j] = mnd_nbr + "." + string(mnd_select) + " ".

    if global_user_lang = "" then do:
       assign menu_title[j] = menu_title[j] + mnd_label.
    end. /* global_user_lang */
    else do:
        find mnt_det where mnt_nbr = mnd_nbr
                       and mnt_select = mnd_select
                       and mnt_lang = global_user_lang no-lock no-error.
        if available mnt_det then
           assign menu_title[j] = menu_title[j] + mnt_label.
    end. /* else */
*/

    /*
    DO PASSWORD CHECKING
    LOOK AT THIS LEVEL UP TO THE LAST CHECKED MENU LEVEL
    TO SEE IF PROTECTED
    */
/*G1VJ*
*  /*CALL MFSEC.P TO CORRECTLY LOOK AT ALL PATHS TO THIS ITEM. */
*    do for mnddet:
*        find first mnddet where mnddet.mnd_nbr = mnd_det.mnd_nbr
*                           and mnddet.mnd_select = mnd_det.mnd_select no-lock no-error.
*        repeat while available mnddet and mnddet.mnd_nbr <> "":
*            {mfsec.i "mnddet"}
*            if not can_do_menu then do:
*                {gprun.i ""gpmsg.p""
*                  "(input 23, input 3)"
*                }
*                /* Password does not allow access to this function. */
*                leave main-loop.  /* not sure if this is explicit enough to exit procedure */
*            end. /* if not can_do_menu */
*            if mnddet.mnd_nbr = menu then
*                leave.
*            passnbr = mnddet.mnd_nbr.
*            find first mnddet where mnddet.mnd_exec = passnbr
*                no-lock no-error.
*        end. /* repeat */
*    end. /* do for mnddet */
*G1VJ*/
/*G1VJ*/{gprun1.i ""mfsec.p"" "(input mnd_det.mnd_nbr,
/*G1VJ*/                        input mnd_det.mnd_select,
/*G1VJ*/                        input true,  /* can display error */
/*G1VJ*/                        output can_do_menu)"
/*G1VJ*/}
/*G1VJ*/if can_do_menu = false then leave main-loop.

    assign
      execname = mnd_exec
      run_file = execname.

    if not can-find(first mnd_det where mnd_nbr = execname) then do:
       assign isaprogram = yes.
    end. /* not can-find */
    else do:
        /* IT IS ANOTHER MENU, BUT IF FROM TOP LEVEL VIA .selection */
        /* DONT PERMIT IT */
        if cselection begins "." then do:
            {gprun.i ""gpmsg.p""
              "(input 61, input 3)"
            }
            /* SELECTION OF SUBMENUS PERMITTED FROM MAIN MENU ONLY */
            leave.
        end. /* if cselection begins ... */
    end. /* else */
end. /* if numericselection */
else do:
    /* THEY ENTERED A MENU SELECTION NAME OR A PROGRAM NAME, */
    /* SEE IF IT IS IN mnd_det AND CHECK PASSWORD. */
    assign
      execname = cselection
      isaprogram = yes
      thismenu = ""
      thisselection = 0.

    /* SEE IF THEY ENTERED A MENU SELECTION NAME. */
/*J2DD** find first mnd_det where mnd_name = cselection no-lock no-error. **/
/*J2DD*/ for first mnd_det
/*J2DD*/ fields(mnd_exec mnd_name mnd_nbr mnd_select)
/*J2DD*/ where mnd_name = cselection no-lock: end.

    if available mnd_det then do:
        /*
        DO PASSWORD CHECKING
        LOOK AT THIS LEVEL UP TO THE LAST CHECKED MENU LEVEL
        TO SEE IF PROTECTED
        */
/*G1VJ*
*  /*CALL MFSEC.P TO CORRECTLY LOOK AT ALL PATHS TO THIS ITEM. */
*        do for mnddet:
*            find first mnddet where mnddet.mnd_nbr = mnd_det.mnd_nbr
*                                and mnddet.mnd_select = mnd_det.mnd_select
*                                no-lock no-error.
*            repeat while available mnddet and mnddet.mnd_nbr <> "":
*                {mfsec.i "mnddet"}
*                if not can_do_menu then do:
*                    {gprun.i ""gpmsg.p""
*                      "(input 23, input 3)"
*                    }
*                    /* Password does not allow access to this function. */
*                    leave main-loop. /* not sure if this is explicit enough to leave procedure */
*                end. /* if not can_do_menu */
*                if mnddet.mnd_nbr = menu then
*                    leave.
*                passnbr = mnddet.mnd_nbr.
*                find first mnddet where mnddet.mnd_exec = passnbr
*                    no-lock no-error.
*            end. /* repeat */
*        end. /* do for mnddet */
*G1VJ*/
/*G1VJ*/{gprun1.i ""mfsec.p"" "(input mnd_det.mnd_nbr,
/*G1VJ*/                        input mnd_det.mnd_select,
/*G1VJ*/                        input true,  /* can display error */
/*G1VJ*/                        output can_do_menu)"
/*G1VJ*/}
/*G1VJ*/if can_do_menu = false then leave main-loop.

        assign
          thismenu = mnd_nbr
          thisselection = mnd_select
          execname = mnd_exec
          run_file = execname.

        if can-find(first mnd_det where mnd_nbr = execname) then do:
            assign isaprogram = no.
            if menu <> "0" then do:
                {gprun.i ""gpmsg.p""
                  "(input 61, input 3)"
                }
                leave.
            end. /* if menu <> "0" */
        end. /* if can-find */
    end. /* if available mnd_det */
    else do:
       assign run_file = execname.
/*
        if index(run_file,".w") > 0 then
            run_file = replace(run_file, ".w", ".p").
*/
/*        if index(run_file,".p") = 0 then
            run_file = run_file + ".p".                               *G2RK*/

/* ADDED ~.. SO THAT MATCHES FUNCTION WORKS CORRECTLY      */ /*L0MB*/
           if index(run_file,".":U) <> 0 then do:             /*G2RK*/
              assign new-exec-pgm-1 = run_file.               /*G2RK*/
              OVERLAY(new-exec-pgm-1,index(run_file,".":U),   /*G2RK*/
                     length(run_file,"character":U),          /*G2RK*/
/*                   "character":U) = "*":U.                  /*G2RK*/ **L0MB*/
                     "character":U) = "~..":U.                         /*L0MB*/
              assign new-exec-pgm-1 = trim(new-exec-pgm-1).   /*G2RK*/
           end.                                               /*G2RK*/
/*         else assign new-exec-pgm-1 = run_file + "*":U.     /*G2RK*/ **L0MB*/
           else assign new-exec-pgm-1 = run_file + "~..":U.            /*L0MB*/


/*G1VJ*/  /* If this program is a substituion for another with an mnd_det, then
/*G1VJ*/     check that mnd_det's security.
/*G1VJ*/  */
/*/*G1VJ*/for each mnds_det no-lock where mnds_exec_sub = run_file, */ /*G2RK*/
/*/*G1VJ*/    each mnd_det no-lock where mnd_exec = mnds_exec:      */ /*G2RK*/

/*J2DD** BEGIN DELETE **
 * /*G1VJ*/for each mnds_det no-lock where mnds_exec_sub matches new-exec-pgm-1:
 *                                                                     /*G2RK*/
 **END DELETE **/

/*J2DD*/    for each mnds_det
/*J2DD*/    fields(mnds_exec mnds_exec_sub)
/*J2DD*/    no-lock where mnds_exec_sub matches new-exec-pgm-1:

/* ADDED ~.. SO THAT MATCHES FUNCTION WORKS CORRECTLY     */ /*L0MB*/
           if index(mnds_exec,".":U) <> 0 then do:           /*G2RK*/
              assign new-exec-pgm-2 = mnds_exec.             /*G2RK*/
              OVERLAY(new-exec-pgm-2,index(mnds_exec,".":U), /*G2RK*/
                      length(mnds_exec,"character":U),       /*G2RK*/
/*                   "character":U) = "*":U.                 /*G2RK*/  **L0MB*/
                     "character":U) = "~..":U.                         /*L0MB*/
              assign new-exec-pgm-2 = trim(new-exec-pgm-2).  /*G2RK*/
           end.                                              /*G2RK*/
/*         else assign new-exec-pgm-1 = run_file + "*":U.    /*G2RK*/  **L0MB*/
           else assign new-exec-pgm-1 = run_file + "~..":U.            /*L0MB*/

/*J2DD** for each mnd_det no-lock where mnd_exec matches new-exec-pgm-2:
                                                         /*G2RK*/ **/
/*J2DD*/    for each mnd_det
/*J2DD*/    fields(mnd_exec mnd_name mnd_nbr mnd_select)
/*J2DD*/    no-lock where mnd_exec matches new-exec-pgm-2:

/*G1VJ*/   {gprun1.i ""mfsec.p"" "(input mnd_det.mnd_nbr,
/*G1VJ*/                           input mnd_det.mnd_select,
/*G1VJ*/ /* can display message */ input true,
/*G1VJ*/                           output can_do_menu)"
/*G1VJ*/   }
/*G1VJ*/   if can_do_menu = false then leave main-loop.
          end.                                                       /*G2RK*/
/*G1VJ*/end.

/*J2DD** BEGIN DELETE **
 * /*        find first mnd_det where mnd_exec = run_file             *G2RK*/
 *       find first mnd_det where mnd_exec matches new-exec-pgm-1  /*G2RK*/
 *           no-lock no-error.
 **J2DD** END DELETE **/

/*J2DD*/ for first mnd_det
/*J2DD*/ fields(mnd_exec mnd_name mnd_nbr mnd_select)
/*J2DD*/ where mnd_exec matches new-exec-pgm-1 no-lock: end.

        if available mnd_det then do:
            assign thismenu = mnd_nbr
                   thisselection = mnd_select.                    /*G2RK*/

/*        for each mnd_det no-lock where mnd_exec = run_file:     *G2RK*/
/*J2DD** for each mnd_det no-lock where mnd_exec matches new-exec-pgm-1:
                                                              /*G2RK*/ **/
/*J2DD*/    for each mnd_det
/*J2DD*/    fields(mnd_exec mnd_name mnd_nbr mnd_select)
/*J2DD*/    no-lock where mnd_exec matches new-exec-pgm-1:
                /*
                DO PASSWORD CHECKING
                LOOK AT THIS LEVEL UP TO THE LAST CHECKED MENU LEVEL
                TO SEE IF PROTECTED
                */
/*G1VJ*
*  /*CALL MFSEC.P TO CORRECTLY LOOK AT ALL PATHS TO THIS ITEM. */
*               do for mnddet:
*                    find first mnddet where mnddet.mnd_nbr = mnd_det.mnd_nbr
*                                        and mnddet.mnd_select = mnd_det.mnd_select
*                                        no-lock no-error.
*                    repeat while available mnddet and mnddet.mnd_nbr <> "":
*                        {mfsec.i "mnddet"}
*                        if not can_do_menu then do:
*                            {gprun.i ""gpmsg.p""
*                              "(input 23, input 3)"
*                            }
*                            /* Password does not allow access to this function. */
*                            leave main-loop. /* not sure this will leave procedure */
*                        end. /* if not can_do_menu */
*                        if mnddet.mnd_nbr = menu then
*                            leave.
*                        passnbr = mnddet.mnd_nbr.
*                        find first mnddet where mnddet.mnd_exec = passnbr
*                            no-lock no-error.
*                    end. /* repeat */
*                end. /* do for mnddet */
*G1VJ*/
/*G1VJ*/       {gprun1.i ""mfsec.p"" "(input mnd_det.mnd_nbr,
/*G1VJ*/                               input mnd_det.mnd_select,
/*G1VJ*/                               input true,  /* can display error */
/*G1VJ*/                               output can_do_menu)"
/*G1VJ*/       }
/*G1VJ*/       if can_do_menu = false then leave main-loop.

            end. /* for each mnd_det */
        end. /* if available mnd_det */
    end. /* else */
end. /* else */

if isaprogram then do:
    /*
    IT IS EITHER A MENU PROGRAM SELECTION
    OR AN ACTUAL PROGRAMNAME,
    SO FIND IT AND IF FOUND RUN IT
    */
    if execname = "QUIT" then
        leave.
/*    run_file = execname. */

    if index(run_file,".") > 0 then
      assign run_file = substr(run_file,1,index(run_file,".") - 1).

    assign
    run_file = global_user_lang_dir + substr(run_file,1,2)  + "/" + run_file.

/*** DON'T TRY TO FIND THE PROGRAM UNTIL AFTER CHECKING FOR SUBSTITUTIONS***
    if search(run_file + ".r") = ? and
       search(run_file + ".p") = ?
        /* *.w is valid for custom code */     /*G2RK*/
        and search(run_file + ".w") = ?        /*G2RK*/
       then do:
        /* NOW LOOK IN THE MAIN DIRECTORY */
        run_file = substr(run_file, length(global_user_lang_dir) + 4,50).
        if search(run_file + ".r") = ? and
           search(run_file + ".p") = ?
            /* *.w is valid for custom code */ /*G2RK*/
            and search(run_file + ".w") = ?    /*G2RK*/
           then do:
            {mfmsg02.i 7705 4 string(thisselection)}
            /* "Selection not currently installed: " string(this selection) */
            /* message "Selection " + string(thisselection) + " (Program " + execname
                    + ") not currently installed.". */
            leave.
        end. /* if search(run_file... */
    end. /* if search(run_file... */
*** End Removed Section *****/

/*J2DD** find mnd_det where mnd_nbr = thismenu and mnd_select = thisselection**/
/*J2DD** no-lock no-error.                                                   **/
/*J2DD*/ for first mnd_det fields(mnd_exec mnd_name mnd_nbr mnd_select)
/*J2DD*/ where mnd_nbr = thismenu and mnd_select = thisselection no-lock: end.

/*    {mfmenu.i} */
    assign help_exec = execname.

    /* FIND PRINTER DEFAULT */
    assign savemenu = thismenu
           saveselection = thisselection.
    assign thismenu = thismenu + "." + string(thisselection).
    {mfprdef.i thismenu}
     assign thismenu = savemenu
            thisselection = saveselection.

end. /* if isaprogram */


assign
  passed = yes /* if we get here, all is well. */
  isProgram = isaprogram
  pgm-name = execname.

/* now that everything has been validated, make sure we get the right title */
if numericselection then do:
    {gprun.i ""gpns2lbl.p""
      "(thismenu, thisselection)"
    }
    assign pgm-label = return-value.
end.
else do:
    {gprun.i ""gpnm2lbl.p""
      "(input execname, output pgm-label)"
    }
end.
end. /* do */
